<template>
  <tm-app class="app-container">
    <tm-navbar :title="workTitle" v-if="showPrimaryOrDetail==='Primary'"></tm-navbar>
    <tm-navbar :title="formTitle" v-if="showPrimaryOrDetail==='Detail'" :hideBack="true">
      <template v-slot:left>
        <tm-icon _class="pointer pb-12 pt-12 px-24" name="tmicon-angle-left" @click="switchToForm('Primary')"></tm-icon>
      </template>
    </tm-navbar>
    <view class="content-container">
      <view v-if="!hasConfig" class="full-height">
        <workState style="height: 100%" :type="workSubType"/>
      </view>
      <view v-else>
        <workMain 
          v-if="showPrimaryOrDetail==='Primary'" 
          :service="service" 
          :node="node" 
          :fields="fields" 
          :type="showPrimaryOrDetail" 
          :rules="rules" 
          :workFormData="workPrimaryFormData" 
          :workDetailData="workDetailFormData"
          :detailFormData="detailForm"
          :content="content"
          :btnRules="btnRules"
          @ValuesChange="workValuesChange" 
          @changeType="switchToForm" 
          @validationChange="handleValidationChange"
          @deleteDetailData="deleteDetailData"/>
        <workMain 
          v-if="showPrimaryOrDetail==='Detail'"
          :fields="detailFields"
          :workFormData="workDetailFormData![detailFormId].find((item:any) => item.nodeId === detailNodeId)!.after.find((item:any) => item.id === detailId)" 
          @ValuesChange="workValuesChangeDetail" 
          @validationChange="handleValidationChange"/>
        <workBtn :type="showPrimaryOrDetail" :canSubmit="canSubmit" @save="save" @delete="deleteChange" :isdraft="isdraft"/>
      </view>
    </view>
  </tm-app>
</template>

<script lang="ts" setup>
import { ref, shallowRef,onMounted,getCurrentInstance, nextTick } from 'vue'
import workState from '@/components/work/workState.vue'
import workMain from '@/components/work/workMain.vue'
import workBtn from '@/components/work/workBtn.vue'
import { onLoad } from '@dcloudio/uni-app'
import orgCtrl from '@/ts/controller'
import { AddNodeType } from '@/utils/work'
import WorkFormService from '@/ts/core/work/scripting/WorkFormService'
import { setDefaultField } from '@/ts/core/work/scripting/FormService';
import FormService from '@/ts/core/work/scripting/FormService';
import { getNodeByNodeId } from '@/utils/work';
import { mapErrorToValidateInfo } from '@/ts/core/work/scripting/js/util'
import { kernel,schema,model } from '@/ts/base';
import { cloneDeep } from 'lodash';
// 是否有配置项的标志，后续会根据实际业务逻辑来设置
const hasConfig = ref(false)
const canSubmit = ref(false)
const params = ref()
const node = ref<model.WorkNodeModel|undefined>(undefined)
const workTitle = ref('办事名称')
const formTitle = ref('表单名称')
const service = shallowRef<WorkFormService>()
const service_current = ref<any>(null);
const fields = ref<(schema.XGroups | model.FieldModel)[]>()
const detailFields = ref<(schema.XGroups | model.FieldModel)[]>()
const workPrimaryFormData = ref<schema.XThing|undefined>()
const rules = ref()
const btnRules = ref()
const detailForm = ref()
const workDetailFormData = ref({})
const showPrimaryOrDetail = ref('Primary')
const detailId = ref()
const detailNodeId = ref()
const detailFormId = ref()
const applyCurrent = ref()
const loading = ref(false);
const staggingId = ref<string|undefined>(undefined)
const staggingType = ref<string|undefined>(undefined)
const staggingContent = ref<string>('')
const content = ref('')
const staggingInstance = ref()
const isdraft = ref(false)
const workSubType = ref('unconfigured')
const gatewayData = ref(new Map<string, string[]>())
onLoad(async(options) => {
  if (!options) return
  if (!options.id) return
  if (options) {
    try {
      // 解码并解析参数
      const parsedData = options
      params.value = parsedData // 存储参数
      uni.showLoading({ title: '加载中...' })
    } catch (error) {
      console.error('解析参数错误:', error)
    }
  }
})
onMounted(() => {
  const instance = getCurrentInstance()!.proxy
  const eventChannel = instance!.getOpenerEventChannel();
  if (params.value) {
    searchWork()
  }
  eventChannel.on('workData',async function(data) {
    staggingType.value = data.type
    if(staggingType.value){
      isdraft.value = true
    }
    staggingId.value = data.data
    staggingContent.value = data.content
    if(staggingType.value === 'draft'){
      staggingInstance.value = data.instance
    }
    await searchWork()
  })
})
const handleValidationChange = (isValid: boolean) => {
  canSubmit.value = isValid
}
const searchWork = async () => {
  try {
    if (!params.value) {
      uni.hideLoading()
      return
    }
    const fileData = await orgCtrl.searchWork(
      params.value.belongId,
      params.value.id
    )
    if (!fileData) {
      hasConfig.value = false
      uni.hideLoading()
      return
    }
    const apply = await fileData.createApply(undefined, undefined)
    if (!apply) {
      hasConfig.value = false
    } else {
      workTitle.value = apply.metadata.title
      applyCurrent.value = apply
      if (
        ['财务', '总账'].includes(apply.applyType) ||
        apply.instanceData.node.children?.type !== AddNodeType.END
      ) {
        init()
      }
    }
    uni.hideLoading()
  } catch (error) {
    uni.hideLoading()
    uni.showToast({
      title: '加载失败',
      icon: 'error'
    })
  }
}
const init = () => {
  if(staggingInstance.value){
    const parsedData = JSON.parse(staggingInstance.value.data);
    Object.assign(applyCurrent.value.instanceData, parsedData, {
      node: applyCurrent.value.instanceData.node
    });
  }
  service.value = new WorkFormService(
    applyCurrent.value.target,
    applyCurrent.value.instanceData,
    true,
    applyCurrent.value.reception
  )
  hasConfig.value = true
  const ret = service.value.init()
  if (ret instanceof Error) {
    if (Array.isArray(ret.cause)) {
      service.value.handlingResult(
        ret.cause.map(e => mapErrorToValidateInfo(e, '初始化'))
      )
    } else {
      service.value.handlingResult([mapErrorToValidateInfo(ret, '初始化')])
    }
  }
  node.value = getNodeByNodeId(applyCurrent.value.instanceData.node.id, applyCurrent.value.instanceData.node);
  btnRules.value = applyCurrent.value.instanceData.node.forms
  initForm()
}
const getData = () => {
  let d: schema.XThing | undefined;
  d = service_current.value!.formData.after.at(-1);
  if (d&&node.value?.primaryForms[0].id) {
      service.value!.updatePrimaryData(node.value?.primaryForms[0].id, d);
      service_current.value!.initRules(d);
  }
  return d;
};
const initForm = () => {
  if(service.value && node.value && node.value.primaryForms.length > 0){
    service_current.value = new FormService(node.value.primaryForms[0] as schema.XForm, service.value);
    if(node.value.primaryForms[0].typeName === '主表'||node.value.primaryForms[0].typeName === '表单'){
      const data = getData();
      workPrimaryFormData.value = data
      if(service_current.value.fields){
        const attributes: (schema.XGroups | model.FieldModel)[] = cloneDeep(service_current.value.fields);
        if(service_current.value.form.groups?.length){
          service_current.value.form.groups.forEach((group:any) => {
            attributes.splice(group.index, 0, group);
          });
        }
        fields.value = attributes;
        rules.value = [...(service_current.value.formData?.rules ?? []),...(service_current.value.work?.model.rules ?? [])]
        // const rules = [...(service_current.value.formData?.rules ?? []),...(service_current.value.work?.model.rules ?? [])].filter((a) => a.destId == field.id)
      }
    }
  }
  if(node.value && service.value ) {
    detailForm.value = [...node.value.detailForms]
    node.value.detailForms.forEach((item:any) => {
      const formData = service.value!.getFormData(item, node.value!.id, '子表')
      if (formData) {
        if(!workDetailFormData.value[item.id]){
          workDetailFormData.value[item.id] = []
        }
        if(staggingInstance.value && workDetailFormData.value[item.id][0].after.length === 0){
          //草稿箱进的数据
          workDetailFormData.value[item.id] = []
        }
        if(staggingType.value !== 'create'){
          workDetailFormData.value[item.id].push(formData)
        }
      }
    })
  }
};
const workValuesChange = (field:string, value:any)=>{
  if(field==='content'){
    content.value = value
  }else{
    if(!service_current.value) return
    service_current.value.onValueChange(field, value,workPrimaryFormData.value)
  }
}
const workValuesChangeDetail = (field:string, currentvalue:any)=>{
  if(workDetailFormData.value){
    workDetailFormData.value[detailFormId.value].find((item:any) => item.nodeId === detailNodeId.value)!.after.find((item:any) => item.id === detailId.value)![field] = currentvalue
  }
}

const switchToForm = async (type:string,formType?:string,nodeId?:string,id?:string,formId?:string) => {
  showPrimaryOrDetail.value = type
  if(formType === 'edit' &&workDetailFormData.value && service.value && id && nodeId && formId) {
    detailFields.value = service.value.model.fields[formId]
    formTitle.value = workDetailFormData.value![formId].find((item:any) => item.nodeId === nodeId)!.after.find((item:any) => item.id === id)!.name
    detailId.value = id
    detailNodeId.value = nodeId
    detailFormId.value = formId
  }
  if(formType === 'add' && service.value &&nodeId&& formId) {
    const res = await kernel.createThing(service.value.belong.id, [], '');
    if (res.success && Array.isArray(res.data) && res.data.length > 0) {
      await setDefaultField(res.data[0], service.value.model.fields[formId], service.value.belong);
      const initialValues = res.data[0];
      initialValues.name = workDetailFormData.value[formId].find((item:any) => item.nodeId === nodeId)?.formName as string
      workDetailFormData.value[formId].find((item:any) => item.nodeId === nodeId)!.after.push(initialValues)
      detailFields.value = service.value.model.fields[formId]
      formTitle.value = initialValues.name
      detailId.value = initialValues.id
      detailNodeId.value = nodeId
      detailFormId.value = formId
    }
  }
}
const save = async() => {
  //保存和提交
  if(showPrimaryOrDetail.value==='Primary'){
    if (loading.value) return;
    loading.value = true;
    try {
      applyCurrent.value.instanceData.data = {
        ...applyCurrent.value.instanceData.data,
        ...workDetailFormData.value
      }
      // 创建办事实例
      const instance = await applyCurrent.value.createApply(
        applyCurrent.value.target.spaceId,
        content.value,
        new Map() // 自由节点之类的再配置
      );

      if (instance) {
        // 提交成功
        uni.showToast({
          title: '提交成功',
          icon: 'success'
        });
        hasConfig.value = false
        workSubType.value = 'success'
      } else {
        uni.showToast({
          title: '提交失败',
          icon: 'error'
        });
      }
    } catch (error) {
      uni.showToast({
        title: '提交失败：' + error,
        icon: 'error'
      });
    } finally {
      loading.value = false;
    }
  }else{
    await switchToForm('Primary')
  }
}
const deleteChange = async() => {
  //存草稿和删除
  if(showPrimaryOrDetail.value==='Primary'&&staggingType.value!==undefined){
    applyCurrent.value.instanceData.data = {
      ...applyCurrent.value.instanceData.data,
      ...workDetailFormData.value
    }
    //存草稿只有列表办事才行
    const info: { content: string } = { content:staggingContent.value };
    const instance = await applyCurrent.value.staggingApply(
      info.content,
      gatewayData.value,
      orgCtrl.user.workStagging,
      staggingId.value,
    );
    if(instance){
      orgCtrl.user.workStagging.cache.push(instance)
      uni.showToast({
        title: '暂存成功',
        icon: 'success'
      });
      hasConfig.value = false
      workSubType.value = 'draft'
    }else{
      uni.showToast({
        title: '暂存失败',
        icon:'error'
      });
    }
  }else{
    //删除
    deleteDetailData(detailNodeId.value,detailId.value)
  }
}
const deleteDetailData = async(nodeId?:string,id?:string)=>{
  if (!nodeId || !id || !workDetailFormData.value) return
  const detailForm = workDetailFormData.value[detailFormId.value].find(item => item.nodeId === nodeId)
  if (detailForm && detailForm.after) {
    const index = detailForm.after.findIndex(item => item.id === id)
    if (index !== -1) {
      detailForm.after.splice(index, 1)
      await switchToForm('Primary')  
    }
  }
}

</script>

<style scoped>
.app-container {
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.content-container {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.full-height {
  height: 100%;
  display: flex;
  flex-direction: column;
}
</style>
